package com.zg.job.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Maps;
import com.zg.common.core.dao.system.SysJob;
import com.zg.common.core.dao.system.SysJobDao;
import com.zg.common.core.util.SpringUtil;
import com.zg.job.enm.JobStateEnum;
import com.zg.job.quartz.CommonJobLauncher;
import com.zg.job.service.BatchService;
import com.zg.job.service.QuartzService;
import com.zg.job.syscode.Constant;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Zxb
 */
@Slf4j
@Service
@AllArgsConstructor
public class QuartzServiceImpl implements QuartzService {

    private Scheduler scheduler;
    private SysJobDao taskService;
    private BatchService batchService;

    public List<SysJob> listSysJob(){
        List<SysJob> list= taskService.list();
        if(!list.isEmpty()){
            return list.stream().filter(t-> !StringUtils.equals(t.getState(),JobStateEnum.下线.name())).collect(Collectors.toList());
        }
        return list;
    }

    public List<SysJob> genJob() throws ClassNotFoundException {
        log.info("加载所有已配置的任务。。。");
        List<SysJob> taskList = listSysJob();
        log.info("总共加载到{}个任务。。。", taskList.size());
        List<SysJob> list  = Lists.newArrayList();
        for(SysJob sysJob : taskList){
            //TODO:暂时不考虑job状态
            log.info("添加任务...id:{},taskName:{},cron:{}",sysJob.getId(),sysJob.getName(),sysJob.getCron());
            SysJob sysJob1 = batchService.gen(sysJob);
            list.add(sysJob1);
        }
        return list;
    }

    @Override
    public void startAll() throws Exception {
        //启动任务管理器
        scheduler.start();
        //只查询运行态的任务
        List<SysJob> list = genJob();
        if (CollectionUtil.isEmpty(list)) {
            if (log.isInfoEnabled()) {
                log.info("没有找到定时任务");
            }
            return;
        }
        for (SysJob job : list) {
            addJob(job);
            job.setState(JobStateEnum.运行.name());
            taskService.updateById(job);
        }
        if (log.isInfoEnabled()) {
            log.info("所有任务已经启动...");
        }
    }

    @Override
    public void addJob(SysJob job) throws SchedulerException {
        String identity = "trigger-" + job.getName();
        //JobDetail jobDetail = JobBuilder.newJob(DiyJob.class).withIdentity(job.getName()).build();

        JobDetail jobDetail= JobBuilder.newJob(CommonJobLauncher.class)
                .withIdentity(job.getName(), job.getJobGroup())
                .build();
        //jobDetail.getJobDataMap().put(job.getCode(), job);
        jobDetail.getJobDataMap().put(Constant.DEFAULT_TARGET_SERVER,job);

        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());
        /**
         * TODO
         * 秒级的表达式有问题，请详细测试
         */
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(identity)
                .forJob(jobDetail).withSchedule(cronScheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
        log.info("Scheduler实例哈希码：" + scheduler.hashCode());

    }

    @Override
    public void modifyJob(SysJob job, String cron) throws SchedulerException {
        Date date = null;
        String identity = "trigger-" + job.getName();
        TriggerKey triggerKey = new TriggerKey(identity);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        String oldCron = cronTrigger.getCronExpression();
        if (!oldCron.equalsIgnoreCase(cron)) {
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(identity)
                    .withSchedule(cronScheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();

            date = scheduler.rescheduleJob(triggerKey, trigger);
        }
        log.info("date:{}",date);
    }

    @Override
    public void pauseJob(SysJob job) throws SchedulerException {
        JobKey jobKey = new JobKey(job.getName(),job.getJobGroup());
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail != null) {
            scheduler.pauseJob(jobKey);
        }
    }

    @Override
    public void resumeJob(SysJob job) throws SchedulerException {
        JobKey jobKey = new JobKey(job.getName(),job.getJobGroup());

        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail != null) {
            scheduler.resumeJob(jobKey);
        }
    }

    @Override
    public void delJob(SysJob job) throws SchedulerException {
        JobKey jobKey = new JobKey(job.getName(),job.getJobGroup());
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail != null) {
            scheduler.deleteJob(jobKey);
        }
    }




}
